package com.ruoyi.system.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.system.domain.FaultDb;
import com.ruoyi.system.domain.KeyBasket;
import com.ruoyi.system.mapper.FaultDbMapper;
import com.ruoyi.system.service.IKeyBasketService;
import lombok.RequiredArgsConstructor;
import org.apache.xmlbeans.impl.xb.xsdschema.impl.KeybaseImpl;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.FaultSummaryMapper;
import com.ruoyi.system.domain.FaultSummary;
import com.ruoyi.system.service.IFaultSummaryService;
import org.springframework.transaction.annotation.Transactional;


/**
 * 故障总表Service业务层处理
 *
 * @author ruoyi
 * @date 2025-01-20
 */
@Service
@RequiredArgsConstructor
public class FaultSummaryServiceImpl implements IFaultSummaryService {

    private final FaultSummaryMapper faultSummaryMapper;

    private final FaultDbMapper faultDbMapper;

    private final IKeyBasketService keyBasketService;

    /**
     * 查询故障总表
     *
     * @param id 故障总表主键
     * @return 故障总表
     */
    @Override
    public FaultSummary selectFaultSummaryById(Long id) {
        return faultSummaryMapper.selectFaultSummaryById(id);
    }



    @Override
    public List<FaultSummary> selectListByFlag(String flag,  Long number) {
        return faultSummaryMapper.selectListByFlag(flag,  number);
    }

    /**
     * 查询故障总表列表
     *
     * @param faultSummary 故障总表
     * @return 故障总表
     */
    @Transactional
    @Override
    public List<FaultSummary> selectFaultSummaryList(FaultSummary faultSummary) {

        if (faultSummary.getTimeGroup() != null) {
            // 移除多余的字符并提取日期部分
            String dateString = faultSummary.getTimeGroup().replaceAll("[^0-9,\\-]", "");
            // 将字符串按逗号分割
            String[] dateArray = dateString.split(",");
            if (!Objects.equals(dateArray[0], "")) {
                // 创建 SimpleDateFormat 对象，指定日期格式
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                // 创建 List 来存储 Date 对象
                List<Date> dateList = new ArrayList<>();
                // 将每个日期字符串解析为 Date 并添加到列表中
                for (String dateStr : dateArray) {
                    try {
                        Date date = sdf.parse(dateStr);
                        dateList.add(date);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
                faultSummary.setTimeGroup(null);
                faultSummary.setCreateTimes(dateList);
            }
        }
        List<FaultSummary> faultSummaries = faultSummaryMapper.selectFaultSummaryList(faultSummary);
        if (faultSummary.getIsRepeat() != null && faultSummary.getIsRepeat() == 1){
            // 这个你不要修改是我去设置parentFlag的
            updateParentFlag();
            for (FaultSummary faultSummary1:faultSummaries){
                faultSummary1.setFinFlagNum(faultSummaryMapper.findFinFlagNum(faultSummary1.getFinFlag()));
            }
        }
        return faultSummaries;
    }

    /**
     * 修改现有的所有的parentFlag里去
     */
    @Override
    public void updateParentFlag() {
        // 查询出所有的faultSummary
        // 查询出所有keyBasket

        List<FaultSummary> faultSummaries = faultSummaryMapper.selectFaultSummaryList(new FaultSummary());
        if(faultSummaries == null || faultSummaries.isEmpty()) {
            return;
        }
        List<KeyBasket> keyBaskets = keyBasketService.selectKeyBasketList(new KeyBasket());
        if(keyBaskets.isEmpty()) {
            return ;
        }
        List<String> keyList = keyBaskets.stream()
                .map(KeyBasket::getKey)
                .collect(Collectors.toList());
        Map<String, String> keyBasketMap = keyBaskets.stream()
                .collect(Collectors.toMap(
                        KeyBasket::getKey,
                        KeyBasket::getBasket,
                        (existing, replacement) -> existing, // 处理键冲突的情况，这里选择保留现有值
                        HashMap::new
                ));

        for(FaultSummary faultSummary : faultSummaries) {
            String key = faultSummary.getKey();
            // process包含有父类以及他本身的key
            List<String> process = process(faultSummary);
            process.add(key);
            // 我们需要根据key去找他的父类以及他本身的keyBasket
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(key);
            int flag = 0;
            for(String key1 : process) {
                if(keyList.contains(key1) && !Objects.equals(key1, key)) {
                    flag = 1;
                    stringBuilder.append("-");
                    stringBuilder.append(keyBasketMap.get(key1));
                }
            }
            if(flag == 0) {
                faultSummary.setIsParent(0);
            } else {
                faultSummary.setIsParent(1);
            }
            faultSummary.setParentFlag(stringBuilder.toString());
        }

        // 批量修改
        faultSummaryMapper.insertFaultSummaryBatch(faultSummaries);

    }

    // 这个是所有的
    private List<FaultSummary> getParentOrFault(List<FaultSummary> all) {
        for (FaultSummary f : all) {
            // 才去判断
            if (f.getIsRepeat() != 1) {
                String key = UUID.randomUUID().toString().substring(0, 6);
                for (FaultSummary f1 : all) {
                    if (f != f1) {


                        // 判断k的个数
                        if (f1.getIsRepeat() != 1) {
                            List<String> key1 = Arrays.asList(f.getKey().split("\\^")); // 输出：[a,b,c]
                            String[] key2 = f1.getKey().split("\\^");
                            boolean isMatchedGroup1to4 = true;
                            isMatchedGroup1to4 = matchExactGroups(key1, key2);


                            // 如果组1到组4匹配成功，继续检查组5到组8
                            boolean isMatchedGroup5to8 = false;
                            if (isMatchedGroup1to4) {
                                isMatchedGroup5to8 = matchGroups(key1, key2);
                            }

                            if (isMatchedGroup5to8 && isMatchedGroup1to4) {
                                f.setIsRepeat(1);
                                f.setFlag(key);
                                f1.setIsRepeat(1);
                                f1.setFlag(f.getFlag());
                            }


                        }
                        // 判断父亲
//                        if (f1.getIsRepeat() != 1) {
                        process(f, f1, key);
//                        }
                    }
                }

            }
        }
        //
        return all.stream().filter(item -> item.getIsRepeat() != 1).collect(Collectors.toList());
    }


    public static List<String> process(FaultSummary mu) {
        List<String> parent = new ArrayList<>();
        String currentString = mu.getKey();
        boolean changed;
        do {
            changed = false;
            List<String> parts = new ArrayList<>(Arrays.asList(currentString.split("\\^")));
            int lastNonXIndex = -1;
            int currentGroup = -1;

            // 从后往前查找第一个非X项并提取组号
            for (int i = parts.size() - 1; i >= 0; i--) {
                String part = parts.get(i);
                if (!part.startsWith("X")) {
                    Matcher matcher = Pattern.compile("组(\\d+)$").matcher(part);
                    if (matcher.find()) {
                        currentGroup = Integer.parseInt(matcher.group(1));
                        lastNonXIndex = i;
                        break;
                    }
                }
            }

            if (lastNonXIndex == -1 || currentGroup == 1) {
                break; // 无处理项或遇到组1停止
            }

            // 收集所有当前组的非X项索引
            List<Integer> indicesToRemove = new ArrayList<>();
            for (int i = 0; i < parts.size(); i++) {
                String part = parts.get(i);
                if (!part.startsWith("X")) {
                    Matcher matcher = Pattern.compile("组(\\d+)$").matcher(part);
                    if (matcher.find() && Integer.parseInt(matcher.group(1)) == currentGroup) {
                        indicesToRemove.add(i);
                    }
                }
            }

            if (indicesToRemove.isEmpty()) {
                continue;
            }

            int maxIndex = Collections.max(indicesToRemove);

            // 构建保留元素列表及其原索引
            List<String> retainedParts = new ArrayList<>();
            List<Integer> retainedIndices = new ArrayList<>();
            for (int i = 0; i < parts.size(); i++) {
                if (!indicesToRemove.contains(i)) {
                    retainedParts.add(parts.get(i));
                    retainedIndices.add(i);
                }
            }

            // 确定插入位置
            int insertPos = retainedParts.size();
            for (int i = 0; i < retainedIndices.size(); i++) {
                if (retainedIndices.get(i) > maxIndex) {
                    insertPos = i;
                    break;
                }
            }

            // 插入X组号
            retainedParts.add(insertPos, "X" + currentGroup);
            // 他的父类
            currentString = String.join("^", retainedParts);
            // 看是否相同或者是否是父类

            if (!"X1^X2^X3^X4^X5^X6^X7^X8^X9^X10".equals(currentString) && !parent.contains(currentString)) {
                parent.add(currentString);
            }
            // System.out.println(currentString);
            changed = true;
        } while (changed);
        return parent;
    }


    // 判断one是否为mu的父类
    public static String process(FaultSummary mu, FaultSummary one, String key) {

        String currentString = mu.getKey();
        boolean changed;
        do {
            changed = false;
            List<String> parts = new ArrayList<>(Arrays.asList(currentString.split("\\^")));
            int lastNonXIndex = -1;
            int currentGroup = -1;

            // 从后往前查找第一个非X项并提取组号
            for (int i = parts.size() - 1; i >= 0; i--) {
                String part = parts.get(i);
                if (!part.startsWith("X")) {
                    Matcher matcher = Pattern.compile("组(\\d+)$").matcher(part);
                    if (matcher.find()) {
                        currentGroup = Integer.parseInt(matcher.group(1));
                        lastNonXIndex = i;
                        break;
                    }
                }
            }

            if (lastNonXIndex == -1 || currentGroup == 1) {
                break; // 无处理项或遇到组1停止
            }

            // 收集所有当前组的非X项索引
            List<Integer> indicesToRemove = new ArrayList<>();
            for (int i = 0; i < parts.size(); i++) {
                String part = parts.get(i);
                if (!part.startsWith("X")) {
                    Matcher matcher = Pattern.compile("组(\\d+)$").matcher(part);
                    if (matcher.find() && Integer.parseInt(matcher.group(1)) == currentGroup) {
                        indicesToRemove.add(i);
                    }
                }
            }

            if (indicesToRemove.isEmpty()) {
                continue;
            }

            int maxIndex = Collections.max(indicesToRemove);

            // 构建保留元素列表及其原索引
            List<String> retainedParts = new ArrayList<>();
            List<Integer> retainedIndices = new ArrayList<>();
            for (int i = 0; i < parts.size(); i++) {
                if (!indicesToRemove.contains(i)) {
                    retainedParts.add(parts.get(i));
                    retainedIndices.add(i);
                }
            }

            // 确定插入位置
            int insertPos = retainedParts.size();
            for (int i = 0; i < retainedIndices.size(); i++) {
                if (retainedIndices.get(i) > maxIndex) {
                    insertPos = i;
                    break;
                }
            }

            // 插入X组号
            retainedParts.add(insertPos, "X" + currentGroup);
            // 他的父类
            currentString = String.join("^", retainedParts);

            // 看是否相同或者是否是父类
//            boolean matched = matchStrings(currentString, one.getKey());
            Map<Integer, Set<String>> groups1 = parseGroups(currentString);
            Map<Integer, Set<String>> groups2 = parseGroups(one.getKey());

            boolean isMatched1 = isMatch(groups1, groups2);
            if (one.getKey().equals(currentString) || isMatched1) {
                if (StringUtils.isEmpty(mu.getFlag())) {
                    mu.setFlag(key);
                    mu.setIsRepeat(1);
                }
                one.setIsRepeat(1);
                one.setFlag(mu.getFlag());
                break;
            }


            // System.out.println(currentString);
            changed = true;

        } while (changed);

        return currentString;
    }

    public static boolean isMatch(Map<Integer, Set<String>> groups1, Map<Integer, Set<String>> groups2) {
        if (!groups1.keySet().equals(groups2.keySet())) {
            return false;
        }

        List<Map<Integer, String>> combos1 = generateCombinations(groups1);
        List<Map<Integer, String>> combos2 = generateCombinations(groups2);

        Set<Map<Integer, String>> comboSet = new HashSet<>(combos1);
        for (Map<Integer, String> combo : combos2) {
            if (comboSet.contains(combo)) {
                return true;
            }
        }
        return false;
    }

    private static Map<Integer, Set<String>> parseGroups(String input) {
        Map<Integer, Set<String>> groups = new HashMap<>();
        String[] segments = input.split("\\^");
        for (String seg : segments) {
            parseSegment(seg, groups);
        }
        return groups;
    }

    private static void parseSegment(String segment, Map<Integer, Set<String>> groups) {
        Matcher matcher = Pattern.compile("^(.*?)(?:组)?(\\d+)$").matcher(segment);
        if (matcher.find()) {
            String value = matcher.group(1);
            int groupNum = Integer.parseInt(matcher.group(2));
            groups.computeIfAbsent(groupNum, k -> new HashSet<>()).add(value);
        } else {
            throw new IllegalArgumentException("无法解析段: " + segment);
        }
    }

    private static List<Map<Integer, String>> generateCombinations(Map<Integer, Set<String>> groups) {
        List<Integer> sortedGroupNums = new ArrayList<>(groups.keySet());
        Collections.sort(sortedGroupNums);
        List<Map<Integer, String>> result = new ArrayList<>();
        backtrack(sortedGroupNums, groups, 0, new HashMap<>(), result);
        return result;
    }

    private static void backtrack(List<Integer> groupNums, Map<Integer, Set<String>> groups, int index,
                                  Map<Integer, String> current, List<Map<Integer, String>> result) {
        if (index == groupNums.size()) {
            result.add(new HashMap<>(current));
            return;
        }
        int group = groupNums.get(index);
        for (String value : groups.get(group)) {
            current.put(group, value);
            backtrack(groupNums, groups, index + 1, current, result);
            current.remove(group);
        }
    }

    // 分割字符串为组
    private static List<String> splitIntoGroups(String input) {
        return Arrays.asList(input.split("\\^"));
    }

    // 生成所有可能的组合
    private static List<List<String>> generateCombinations(List<List<String>> groupLists) {
        List<List<String>> result = new ArrayList<>();
        result.add(new ArrayList<>());

        for (List<String> groupList : groupLists) {
            List<List<String>> newResult = new ArrayList<>();
            for (List<String> current : result) {
                for (String group : groupList) {
                    List<String> newCombination = new ArrayList<>(current);
                    newCombination.add(group);
                    newResult.add(newCombination);
                }
            }
            result = newResult;
        }
        return result;
    }

    // 处理重复组，生成唯一组列表
    private static List<List<String>> processGroups(List<String> groups) {
        Map<String, List<String>> groupMap = new HashMap<>();
        for (String group : groups) {
            String groupType = group.replaceAll("^[a-zA-Z0-9]+", "");
            groupMap.computeIfAbsent(groupType, k -> new ArrayList<>()).add(group);
        }
        return new ArrayList<>(groupMap.values());
    }

    // 检查两个组合是否匹配
    private static boolean isMatch(List<String> comb1, List<String> comb2) {
        if (comb1.size() != comb2.size()) {
            return false;
        }
        for (int i = 0; i < comb1.size(); i++) {
            if (!comb1.get(i).equals(comb2.get(i))) {
                return false;
            }
        }
        return true;
    }

    // 主匹配函数
    public static boolean matchStrings(String str1, String str2) {
        List<String> groups1 = splitIntoGroups(str1);
        List<String> groups2 = splitIntoGroups(str2);

        List<List<String>> groupLists1 = processGroups(groups1);
        List<List<String>> groupLists2 = processGroups(groups2);

        List<List<String>> combinations1 = generateCombinations(groupLists1);
        List<List<String>> combinations2 = generateCombinations(groupLists2);

        for (List<String> comb1 : combinations1) {
            for (List<String> comb2 : combinations2) {
                if (isMatch(comb1, comb2)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 新增故障总表
     *
     * @param faultSummary 故障总表
     * @return 结果
     */
    @Transactional
    @Override
    public int insertFaultSummary(FaultSummary faultSummary) {
        faultSummary.setIsRepeat(0);
        faultSummary.setIsParent(0);
        //获取故障数据库
        List<FaultDb> faultDbs = faultDbMapper.selectFaultDbList(new FaultDb());
        // 只生成key
        matchingFault(faultSummary, faultDbs);

        // TODO 篮子
        if (faultSummary.getNumber().toString().length() > 10) {
            String string = faultSummary.getNumber().toString();
        }

        // faultSummaryMapper.insertFaultSummary(faultSummary);

        // TODO 插入篮子组
        String key = faultSummary.getKey();
        // 找keyBasket里面 获取里面所有的key怕新来的key有重复
        List<KeyBasket> keyBaskets = keyBasketService.selectKeyBasketList(new KeyBasket());
        List<String> keyStringList = new ArrayList<>();
        if(keyBaskets != null && keyBaskets.size() != 0) {
            for(KeyBasket k :keyBaskets) {
                keyStringList.add(k.getKey());
            }
        }
        // 最终插入数据库的
        List<KeyBasket> cha = new ArrayList<>();
        if(!keyStringList.contains(key)) {
            KeyBasket keyBasket = new KeyBasket();
            keyBasket.setKey(key);;
            String basket = UUID.randomUUID().toString().substring(0, 6);
            keyBasket.setBasket(basket);
            cha.add(keyBasket);
        }
        keyBasketService.insertBatch(cha);


        List<FaultSummary> faultSummaries = faultSummaryMapper.selectFaultSummaryList(new FaultSummary());
        if(faultSummaries.isEmpty()) {
            faultSummary.setIsRepeat(0);
        } else {
            // 处理组的k
            // 主逻辑：遍历faultSummaryList和当前的faultSummary进行匹配

            if (faultSummaries != null && !faultSummaries.isEmpty()) {
                for (FaultSummary fs1 : faultSummaries) {
                    if (Objects.equals(faultSummary.getNumber(), fs1.getNumber())) {
                        // 获取 faultSummary1 的 key，并将其分割
                        String[] faultSummaryDetails = fs1.getKey().split("\\^");

                        // 获取过滤后的 faultSummary 中的 key
                        List<String> filteredFaultSummaryDetails = getFilteredFaultSummaryDetails(faultSummary);

                        // 检查组1到组4是否完全匹配
                        boolean isMatchedGroup1to4 = true;
                        isMatchedGroup1to4 = matchExactGroups(filteredFaultSummaryDetails, faultSummaryDetails);


                        // 如果组1到组4匹配成功，继续检查组5到组8
                        boolean isMatchedGroup5to8 = false;
                        if (isMatchedGroup1to4) {
                            isMatchedGroup5to8 = matchGroups(filteredFaultSummaryDetails, faultSummaryDetails);
                        }


                        // 如果组1到组4完全匹配，且组5到组8有两个及以上相同的元素，或者组1到组4没有匹配，且组5到组8有两个及以上相同的元素，则认为是重复故障
                        if (isMatchedGroup1to4 && isMatchedGroup5to8) {
                            String flag = fs1.getFlag();
                            if (flag == null) {
                                flag = UUID.randomUUID().toString().substring(0, 6);  // 生成一个6位的UUID
                            }
                            // 设置isRepeat为1，表示重复故障
                            faultSummary.setIsRepeat(1);

                            if (fs1.getIsRepeat() == 0) {
                                fs1.setIsRepeat(1);
                            }
                            faultSummary.setFlag(flag);
                            fs1.setFlag(flag);
                            if (!flag.equals(fs1.getFlag())) {
                                faultSummaryMapper.updateFaultSummary(fs1);
                            }
                        }
                    }
                }


            }
        }

        // 再来设置finFlag的
//        faultSummaries = faultSummaryMapper.selectFaultSummaryList(new FaultSummary());
//        if (faultSummaries != null && !faultSummaries.isEmpty()) {
//            for(FaultSummary f : faultSummaries) {
//                String finFlag = UUID.randomUUID().toString().substring(0, 6);
//                if(Objects.equals(f.getNumber(), faultSummary.getNumber())) {
//                    if((Objects.equals(f.getFlag(), faultSummary.getFlag()) && f.getIsRepeat() == 1 && faultSummary.getIsRepeat() == 1) || (Objects.equals(f.getParentFlag(), faultSummary.getParentFlag()) && f.getIsParent() == 1 && faultSummary.getIsParent() == 1)) {
//                        if(!StringUtils.isEmpty(f.getFinFlag())) {
//                            faultSummary.setFlag(f.getFinFlag());
//                            break;
//                        } else {
//                            f.setFinFlag(finFlag);
//                            faultSummary.setFlag(finFlag);
//                            faultSummaryMapper.updateFaultSummary(f);
//                        }
//                    }
//                }
//            }
//        }


        return faultSummaryMapper.insertFaultSummary(faultSummary);


    }

    // 去重处理
    public static List<String> getDifference(List<String> listA, List<String> listB) {
        // 将列表 B 转换为集合，利用集合查找效率高的特性
        Set<String> setB = new HashSet<>(listB);
        // 用于存储列表 A 中独有的元素
        List<String> result = new ArrayList<>();

        // 遍历列表 A
        for (String element : listA) {
            // 如果元素不在集合 B 中，说明是列表 A 独有的元素
            if (!setB.contains(element)) {
                result.add(element);
            }
        }
        return result;
    }

    @Override
    public List<String> findUniqueDates() {
        return faultSummaryMapper.findUniqueDates();
    }

    /**
     * 修改故障总表
     *
     * @param faultSummary 故障总表
     * @return 结果
     */
    @Override
    public int updateFaultSummary(FaultSummary faultSummary) {
        //获取故障数据库
        List<FaultDb> faultDbs = faultDbMapper.selectFaultDbList(new FaultDb());
        matchingFault(faultSummary, faultDbs);
        return faultSummaryMapper.updateFaultSummary(faultSummary);
    }

    /**
     * 批量删除故障总表
     *
     * @param ids 需要删除的故障总表主键
     * @return 结果
     */
    @Override
    public int deleteFaultSummaryByIds(Long[] ids) {
        return faultSummaryMapper.deleteFaultSummaryByIds(ids);
    }

    /**
     * 删除故障总表信息
     *
     * @param id 故障总表主键
     * @return 结果
     */
    @Override
    public int deleteFaultSummaryById(Long id) {
        return faultSummaryMapper.deleteFaultSummaryById(id);
    }

    @Override
    public int removeFaultSummaryById(Long id) {
        return faultSummaryMapper.updateFaultSummaryFlag(id);
    }

/**
 * 故障匹配（组）
 * @param faultSummaries
 * @return
 */
//    @Override
//    public List<FaultSummary> matchingFaultGroup(List<FaultSummary> faultSummaries) {
//        List<FaultDb> faultDbs = faultDbMapper.selectFaultDbList(new FaultDb());
//        // 使用 Map 分组，key 为 group，value 为相同 group 的 FaultDb 列表
//        Map<String, List<FaultDb>> groupedMap = faultDbs.stream()
//                .collect(Collectors.groupingBy(
//                        FaultDb::getGroup,
//                        TreeMap::new,  // 使用 TreeMap 按照自然顺序（即组名的数字顺序）排序
//                        Collectors.toList()
//                ));
//
//        // 按照 group 的顺序排列并返回
//        List<List<FaultDb>> faultDbList = new ArrayList<>();
//        List<String> groupKeys = new ArrayList<>(groupedMap.keySet());
//        // 按照 group 的顺序将组加入结果列表
//        for (String group : groupKeys) {
//            faultDbList.add(groupedMap.get(group));
//        }
//        for (FaultSummary faultSummary:faultSummaries){
//            String detail = faultSummary.getDetail();
//            StringBuilder keyBuilder = new StringBuilder(); // 用于拼接匹配到的 key
//            boolean allMatched = true; // 是否完全匹配标志
//            int detailPointer = 0; // 记录当前匹配的指针
//            int totalLength = detail.length();
//
//            // 跳过特殊字符，直到遇到字母或数字
//            while (detailPointer < totalLength && !Character.isLetterOrDigit(detail.charAt(detailPointer))) {
//                detailPointer++;
//            }
//
//            // 一轮完整的匹配，直到全部检查完成
//            while (detailPointer < totalLength) {
//                int bestMatchLength = 0; // 本轮匹配到的最佳匹配长度
//                String bestMatchKey = null; // 本轮匹配到的最佳key
//
//                // 遍历每一组 (List<FaultDb>)
//                for (int groupIndex = 0; groupIndex < faultDbList.size(); groupIndex++) {
//                    List<FaultDb> currentGroup = faultDbList.get(groupIndex);
//                    boolean groupMatched = false;
//
//                    // 遍历当前组中的所有 FaultDb 进行匹配
//                    for (FaultDb faultDb : currentGroup) {
//                        String[] faultKeywords = faultDb.getFault().split("-"); // 将 fault 按 "-" 分割成多个关键字
//
//                        // 逐个匹配 fault 关键字
//                        for (String faultKeyword : faultKeywords) {
//                            int matchIndex = detail.indexOf(faultKeyword, detailPointer);
//                            if (matchIndex == detailPointer) {
//                                // 如果当前匹配的关键字更长，更新最佳匹配
//                                if (faultKeyword.length() > bestMatchLength) {
//                                    bestMatchKey = faultDb.getKey();
//                                    bestMatchLength = faultKeyword.length();
//                                }
//                                groupMatched = true;
//                                break; // 匹配到一个关键字后退出当前循环
//                            }
//                        }
//
//                        if (groupMatched) {
//                            break; // 如果匹配到当前组，跳出外层循环
//                        }
//                    }
//                }
//
//                // 如果找到匹配的关键字，更新指针
//                if (bestMatchKey != null) {
//                    keyBuilder.append(bestMatchKey).append("-"); // 拼接最佳匹配的 key
//                    detailPointer += bestMatchLength; // 更新指针，跳过已经匹配的部分
//                } else {
//                    // 如果没有找到匹配的关键字，加入 X
//                    allMatched = false;
//                    keyBuilder.append("X").append("-"); // 未匹配的部分用 X 替代
//                    detailPointer++; // 向后移动指针，继续匹配下一个关键字
//                }
//
//                // 跳过所有特殊字符，直到遇到下一个字母或数字
//                while (detailPointer < totalLength && !Character.isLetterOrDigit(detail.charAt(detailPointer))) {
//                    detailPointer++;
//                }
//            }
//
//            // 设置 key 和 isFail
//            if (keyBuilder.length() == 0) {
//                faultSummary.setKey("未匹配"); // 如果没有匹配到任何内容
//            } else {
//                // 去掉最后的 "-" 号
//                String key = keyBuilder.toString().replaceAll("-$", "");
//                faultSummary.setKey(key);
//            }
//
//            // 设置是否匹配成功
//            faultSummary.setIsFail(allMatched ? 1 : 0);
//        }
//
//        /**
//         * 开始
//         */
//        for (FaultSummary faultSummary:faultSummaries){
//            faultSummary.setCreateTime(new Date());
//            //如果匹配成功
//            //判断是否是重复故障逻辑为，组3、4、5、6、7，有1个重复就算
//            //首先查询相同车号的故障
//            List<FaultSummary> faultSummaryList = faultSummaryMapper.selectFaultSummaryByNumber(faultSummary);
//
//            // 将FaultSummary中的detail字符串通过"-"进行分割
//            String[] faultSummaryDetails = faultSummary.getDetail().split("-");
//
//            // 过滤掉末尾为"X"或者组3-7中的元素
//            List<String> filteredFaultSummaryDetails = new ArrayList<>();
//            for (String detail : faultSummaryDetails) {
//                // 检查是否是"X"且组号是否属于组3到组7
//                if (!detail.equals("X") && !isInGroup3To7(detail)) {
//                    filteredFaultSummaryDetails.add(detail);
//                }
//            }
//
//            // 遍历faultSummary1列表
//            for (FaultSummary fs1 : faultSummaryList) {
//                // 将faultSummary1中的detail字段通过"-"分割
//                String[] faultSummary1Details = fs1.getDetail().split("-");
//
//                // 遍历faultSummary中的每个过滤后的字符串数组元素
//                for (String filteredDetail : filteredFaultSummaryDetails) {
//                    // 遍历faultSummary1中的每个元素，检查是否存在相同的元素
//                    for (String fs1Detail : faultSummary1Details) {
//                        if (filteredDetail.equals(fs1Detail)) {
//                            //如果相同，说明属于同一故障，设置isRepeat为1
//                            faultSummary.setIsRepeat(1);
//                            fs1.setIsRepeat(1);
//                            //设置UUID
//                            String key = UUID.randomUUID().toString().substring(0,6);  // 生成一个6位的UUID
//                            faultSummary.setFlag(key);
//                            fs1.setFlag(key);
//                            faultSummaryMapper.updateFaultSummary(fs1);
//                        }
//                    }
//                }
//            }
//
//        }
//
//        return faultSummaries;
//    }

    /**
     * 故障匹配（组）
     *
     * @param faultSummary
     * @return
     */
    @Override
    public FaultSummary matchingFault(FaultSummary faultSummary, List<FaultDb> faultDbs) {
        // 使用 Map 分组，key 为 group，value 为相同 group 的 FaultDb 列表
        Map<String, List<FaultDb>> groupedMap = faultDbs.stream()
                .collect(Collectors.groupingBy(
                        FaultDb::getGroup,
                        TreeMap::new,  // 使用 TreeMap 按照自然顺序（即组名的数字顺序）排序
                        Collectors.toList()
                ));

        // 按照 group 的顺序排列并返回
        List<List<FaultDb>> faultDbList = new ArrayList<>();
        List<String> groupKeys = new ArrayList<>(groupedMap.keySet());
        // 按照 group 的顺序将组加入结果列表
        for (String group : groupKeys) {
            faultDbList.add(groupedMap.get(group));
        }
        faultDbList.add(faultDbList.get(1));
        faultDbList.remove(1);
        //获取故障 同时把大写字母转换成小写
        String detail = faultSummary.getDetail().toLowerCase();

        StringBuilder keyBuilder = new StringBuilder(); // 用于拼接匹配到的 key

        boolean allMatched = true; // 是否完全匹配标志
        int detailPointer = 0; // 记录当前匹配的指针
        int totalLength = detail.length();
        // 跳过特殊字符，直到遇到字母或数字
        while (detailPointer < totalLength && !Character.isLetterOrDigit(detail.charAt(detailPointer))) {
            detailPointer++;
        }
        // 一轮完整的匹配，直到全部检查完成
        while (detailPointer < totalLength) {
            int bestMatchLength = 0; // 本轮匹配到的最佳匹配长度
            StringBuilder bestMatchKey = null; // 本轮匹配到的最佳key
            // 遍历每一组 (List<FaultDb>)
            for (int groupIndex = 0; groupIndex < faultDbList.size(); groupIndex++) {
                List<FaultDb> currentGroup = faultDbList.get(groupIndex);
                boolean groupMatched = false;
                // 遍历当前组中的所有 FaultDb 进行匹配
                for (FaultDb faultDb : currentGroup) {
                    String[] faultKeywords = faultDb.getFault().split("\\^"); // 将 fault 按 "^" 分割成多个关键字
                    // 逐个匹配 fault 关键字
                    for (String faultKeyword : faultKeywords) {
                        int matchIndex = detail.indexOf(faultKeyword, detailPointer);
                        if (matchIndex == detailPointer) {
                            // 如果当前匹配的关键字更长，更新最佳匹配
                            if (faultKeyword.length() > bestMatchLength) {
                                //如果当前是组2或者组10,则直接加入keyword,后续再将keyword转换为key
                                if (faultDb.getKey().charAt(6) == '2' || (faultDb.getKey().length() > 7 &&  faultDb.getKey().charAt(6) == '1')) {
//                                    String[] split = faultDb.getFault().split("\\^");
                                    bestMatchKey = new StringBuilder(faultKeyword);
                                    //如果是组2和组10以外的，则加入key
                                } else {
                                    bestMatchKey = new StringBuilder(faultDb.getKey());
                                }
                                bestMatchLength = faultKeyword.length();
                                /**
                                 * 如果两个字段相同,两个字段一起保留
                                 */
                            } else if (faultKeyword.length() == bestMatchLength) {
                                //如果key长度相同，则说明不是组1和组10，则可以拼接在一起
                                if (bestMatchKey != null) {
                                    String[] split = bestMatchKey.toString().split("\\^");
                                    if (split[0].length() == faultDb.getKey().length()) {
                                        bestMatchKey.append('^').append(faultDb.getKey());
                                        //长度不相等，则说明一个是组1，一个是组10，则需判断当前是属于组1还是组10
                                    }
                                }
                            }
//                            groupMatched = true;
//                            break; // 匹配到一个关键字后退出当前循环
                        }
                    }
                }
            }
            // 如果找到匹配的关键字，更新指针
            if (bestMatchKey != null) {
                //本轮匹配到的key如果是组1，继续查找前后判断是否是组9
//                if (bestMatchKey.charAt(6) == '1' && detailPointer != 0 && detailPointer != totalLength - 1){{
//                    if (detail.charAt(detailPointer-1))
//                }}
                keyBuilder.append(bestMatchKey).append("^"); // 拼接最佳匹配的 key
                detailPointer += bestMatchLength; // 更新指针，跳过已经匹配的部分
            } else {
                // 如果没有找到匹配的关键字，加入 X
                allMatched = false;
                keyBuilder.append("X").append("^"); // 未匹配的部分用 X 替代
                detailPointer++; // 向后移动指针，继续匹配下一个关键字
            }
            // 跳过所有特殊字符，直到遇到下一个字母或数字
            while (detailPointer < totalLength && !Character.isLetterOrDigit(detail.charAt(detailPointer))) {
                detailPointer++;
            }
        }


        // 设置 key 和 isFail
        if (keyBuilder.length() == 0) {
            faultSummary.setKey("未匹配"); // 如果没有匹配到任何内容
        } else {
            // 去掉最后的 "^" 号
            String key = keyBuilder.toString().replaceAll("\\^$", "");
            faultSummary.setKey(key);

            // 开始重新检索，重新匹配组1和组10
            String[] splits = faultSummary.getKey().split("\\^");
            boolean isGroup10 = true;
            for (int i = splits.length - 1; i >= 0; i--) {
                if (splits[i].equals("X")) {
                    continue;
                }
                //如果当前key是组3，则前面的数字1都为组2
                if (splits[i].length() == 7 && splits[i].charAt(6) == '3') {
                    isGroup10 = false;
                }
                //如果是组10
                if (splits[i].length() < 7 && isGroup10) {
                    splits[i] = groupIntoKey(splits[i], faultDbList.get(9));
                } else if (splits[i].length() < 7) {
                    splits[i] = groupIntoKey(splits[i], faultDbList.get(1));
                }
            }
            faultSummary.setKey(processStrings(splits));
        }
        // 设置是否匹配成功
        faultSummary.setIsFail(allMatched ? 1 : 0);
        faultSummary.setCreateTime(new Date());


        // 先查询相同车号的故障
//        List<FaultSummary> faultSummaryList = faultSummaryMapper.selectFaultSummaryByNumber(faultSummary);

        /**
         * 42342342
         *
         *
         */

        // 主逻辑：遍历faultSummaryList和当前的faultSummary进行匹配
//        for (FaultSummary fs1 : faultSummaryList) {
//            // 获取 faultSummary1 的 key，并将其分割
//            String[] faultSummaryDetails = fs1.getKey().split("\\^");
//
//            // 获取过滤后的 faultSummary 中的 key
//            List<String> filteredFaultSummaryDetails = getFilteredFaultSummaryDetails(faultSummary);
//
//            // 检查组1到组4是否完全匹配
//            boolean isMatchedGroup1to4 = true;
//            isMatchedGroup1to4 = matchExactGroups(filteredFaultSummaryDetails, faultSummaryDetails);
//
//
//            // 如果组1到组4匹配成功，继续检查组5到组8
//            boolean isMatchedGroup5to8 = false;
//            if (isMatchedGroup1to4) {
//                isMatchedGroup5to8 = matchGroups(filteredFaultSummaryDetails, faultSummaryDetails);
//            }
//
//
//            // 如果组1到组4完全匹配，且组5到组8有两个及以上相同的元素，或者组1到组4没有匹配，且组5到组8有两个及以上相同的元素，则认为是重复故障
//            if (isMatchedGroup1to4 && isMatchedGroup5to8) {
//                String flag = fs1.getFlag();
//                if (flag == null) {
//                    flag = UUID.randomUUID().toString().substring(0, 6);  // 生成一个6位的UUID
//                }
//                // 设置isRepeat为1，表示重复故障
//                faultSummary.setIsRepeat(1);
//
//                if (fs1.getIsRepeat() == 0) {
//                    fs1.setIsRepeat(1);
//                }
//                faultSummary.setFlag(flag);
//                fs1.setFlag(flag);
//                faultSummaryMapper.updateFaultSummary(fs1);
//            }
//        }


        return faultSummary;
    }

    // 获取 filteredFaultSummaryDetails 的方法
    private List<String> getFilteredFaultSummaryDetails(FaultSummary faultSummary) {
        // 将 faultSummary 的 key 按照 "-" 分割，并过滤掉 null 和 "X"
        return Arrays.stream(faultSummary.getKey().split("\\^"))
                .filter(Objects::nonNull) // 过滤 null 和 "X"
                .collect(Collectors.toList());
    }

    public static String processStrings(String[] splits) {
        // Step 1: 过滤掉所有的"X"元素，并提取带组号的元素
        List<String> filtered = new ArrayList<>();
        for (String s : splits) {
            if (!s.equals("X")) {
                filtered.add(s);
            }
        }

        // Step 2: 按照组号排序
        Collections.sort(filtered, (a, b) -> {
            int groupA = getGroupNumber(a);
            int groupB = getGroupNumber(b);
            return Integer.compare(groupA, groupB);
        });

        // Step 3: 记录已经出现的组号
        Set<Integer> seenGroups = new HashSet<>();
        for (String s : filtered) {
            seenGroups.add(getGroupNumber(s));
        }

        // Step 4: 创建最终的结果列表
        List<String> result = new ArrayList<>();

        // Step 5: 先添加缺失的X（从X1到X10），保证顺序
        for (int i = 1; i <= 10; i++) {
            if (!seenGroups.contains(i)) {
                result.add("X" + i);
            }
        }

        // Step 6: 将已排序的组号按顺序添加到结果中
        result.addAll(filtered);

        // Step 7: 确保X添加在正确的位置
        List<String> finalResult = new ArrayList<>();
        List<String> remainingX = new ArrayList<>();

        // 添加缺失的X，按顺序放到结果前
        for (int i = 1; i <= 10; i++) {
            if (result.contains("X" + i)) {
                remainingX.add("X" + i);
            }
        }

        // Step 8: 将按顺序加入X，然后加入组号
        finalResult.addAll(remainingX);
        finalResult.addAll(filtered);

        // Step 9: 根据每个条目的最后一个数字进行排序
        Collections.sort(finalResult, (a, b) -> {
            int lastNumA = getLastNumber(a);
            int lastNumB = getLastNumber(b);
            return Integer.compare(lastNumA, lastNumB);
        });

        // Step 10: 用^连接每个字符串并返回最终结果
        return String.join("^", finalResult);
    }

    // 获取字符串最后的数字部分
    private static int getLastNumber(String s) {
        // 如果是X，直接获取数字
        if (s.startsWith("X")) {
            return Integer.parseInt(s.substring(1));
        }
        // 否则，获取组号
        return getGroupNumber(s);
    }


    // 提取组号
    private static int getGroupNumber(String s) {
        Pattern pattern = Pattern.compile("组(\\d+)");
        Matcher matcher = pattern.matcher(s);
        if (matcher.find()) {
            return Integer.parseInt(matcher.group(1));
        }
        return -1; // 默认值，如果没有找到组号
    }


    //判断是否是特殊字符
    public static boolean isDelimiter(char c) {
        switch (c) {
            case ' ':
            case ',':
            case '，':
            case '/':
            case '、':
            case '\\':
            case '|':
            case '-':
                return true;
            default:
                return false;
        }
    }

    public static String groupIntoKey(String s, List<FaultDb> list) {
        for (FaultDb s1 : list) {
            String[] split = s1.getFault().split("\\^");
            for (String s2 : split) {
                if (s.equals(s2)) {
                    return s1.getKey();
                }
            }
        }
        return "X";
    }


    // 精确匹配组的函数（组1到组4专用）
    private boolean matchExactGroups(List<String> filteredFaultSummaryDetails, String[] faultSummaryDetails) {
        // 提取组1到组4的部分
        List<String> group1To4Details = getGroupDetails(filteredFaultSummaryDetails, 1, 4);
        List<String> group1To4DetailsFs1 = getGroupDetails(Arrays.asList(faultSummaryDetails), 1, 4);

        // 先判断组四
        List<String> l1 = new ArrayList<>();
        List<String> l2 = new ArrayList<>();

        for (String s1 : group1To4Details) {
            // 加入X4
            if ("X4".equals(s1) && !l1.contains(s1)) {
                l1.add(s1);
            } else {
                // 加入组四
                String group = extractGroupNumber(s1);
                if ("4".equals(group) && !l1.contains(s1)) {
                    l1.add(s1);
                }

            }
        }

        for (String s1 : group1To4DetailsFs1) {
            // 加入X4
            if ("X4".equals(s1) && !l2.contains(s1)) {
                l2.add(s1);
            } else {
                // 加入组四
                String group = extractGroupNumber(s1);
                if ("4".equals(group) && !l2.contains(s1)) {
                    l2.add(s1);
                }

            }
        }
        // 都只有一个情况
        if (l1.size() == 1 && l2.size() == 1) {
            String s1 = l1.get(0);
            String s2 = l2.get(0);
            if (!s1.equals(s2)) {
                return false;
            }
        }

        // 如果l1的个数大于l2
        if (l1.size() > l2.size()) {
            int flag = 1;
            for (String s1 : l2) {
                if (l1.contains(s1)) {
                    flag = 0;
                }
            }
            if (flag == 1) {
                return false;
            }
        }

        if (l1.size() < l2.size()) {
            int flag = 1;
            for (String s1 : l1) {
                if (l2.contains(s1)) {
                    flag = 0;
                }
            }
            if (flag == 1) {
                return false;
            }
        }

        // 组四上面判断完了

        // 组1到组3 存在两个以及两个以上相同即可
        List<String> all = new ArrayList<>();
        all.add("X1");
        all.add("X2");
        all.add("X3");

        List<String> group1 = new ArrayList<>();
        List<String> group2 = new ArrayList<>();

        for (String s1 : group1To4Details) {
            // 表示X1之类的
            if (all.contains(s1) && !group1.contains(s1)) {
                group1.add(s1);
            } else {
                // 表示组
                String group = extractGroupNumber(s1);
                if (("1".equals(group) || "2".equals(group) || "3".equals(group)) && !group1.contains(s1)) {
                    group1.add(s1);
                }
            }
        }


        for (String s1 : group1To4DetailsFs1) {
            // 表示X1之类的
            if (all.contains(s1) && !group2.contains(s1)) {
                group2.add(s1);
            } else {
                // 表示组
                String group = extractGroupNumber(s1);
                if (("1".equals(group) || "2".equals(group) || "3".equals(group)) && !group2.contains(s1)) {
                    group2.add(s1);
                }
            }
        }

        // 不会出现这个情况  可以不删除
        /*if (group1.size() == 0 && group2.size() == 0) {
            return true;
        }*/

        int count = 0;
        if (group1.size() > group2.size()) {
            for (String s1 : group2) {
                if (group1.contains(s1)) {
                    count++;
                }
            }
        } else {
            for (String s1 : group1) {
                if (group2.contains(s1)) {
                    count++;
                }
            }
        }
        return count >= 2;
    }

    // 匹配部分组（适用于组6到组8，检查两个及以上相同元素）
// 第一个参数是 当前数据的key的分割
// 第二个参数  是查询出来的key
    private boolean matchGroups(List<String> filteredFaultSummaryDetails, String[] faultSummaryDetails) {

        // 先判断组6
        List<String> group1To4Details = getGroupDetails(filteredFaultSummaryDetails, 6, 8);
        List<String> group1To4DetailsFs1 = getGroupDetails(Arrays.asList(faultSummaryDetails), 6, 8);


        // 先判断组六
        List<String> l1 = new ArrayList<>();
        List<String> l2 = new ArrayList<>();

        for (String s1 : group1To4Details) {
            // 加入X6
            if ("X6".equals(s1) && !l1.contains(s1)) {
                l1.add(s1);
            } else {
                // 加入组六
                String group = extractGroupNumber(s1);
                if ("4".equals(group) && !l1.contains(s1)) {
                    l1.add(s1);
                }

            }
        }

        for (String s1 : group1To4DetailsFs1) {
            // 加入X6
            if ("X6".equals(s1) && !l2.contains(s1)) {
                l2.add(s1);
            } else {
                // 加入组六
                String group = extractGroupNumber(s1);
                if ("6".equals(group) && !l2.contains(s1)) {
                    l2.add(s1);
                }

            }
        }
        // 都只有一个情况
        if (l1.size() == 1 && l2.size() == 1) {
            String s1 = l1.get(0);
            String s2 = l2.get(0);
            if (!s1.equals(s2)) {
                return false;
            }
        }

        // 如果l1的个数大于l2
        if (l1.size() > l2.size()) {
            int flag = 1;
            for (String s1 : l2) {
                if (l1.contains(s1)) {
                    flag = 0;
                }
            }
            if (flag == 1) {
                return false;
            }
        }

        if (l1.size() < l2.size()) {
            int flag = 1;
            for (String s1 : l1) {
                if (l2.contains(s1)) {
                    flag = 0;
                }
            }
            if (flag == 1) {
                return false;
            }
        }

        // 组六上面判断完了

        // 下面判断组7与组8  存在一个以及一个以上相同即可
        List<String> all = new ArrayList<>();
        all.add("X7");
        all.add("X8");

        List<String> group1 = new ArrayList<>();
        List<String> group2 = new ArrayList<>();

        for (String s1 : group1To4Details) {
            // 表示X7之类的
            if (all.contains(s1) && !group1.contains(s1)) {
                group1.add(s1);
            } else {
                // 表示组7
                String group = extractGroupNumber(s1);
                if (("7".equals(group) || "8".equals(group)) && !group1.contains(s1)) {
                    group1.add(s1);
                }
            }
        }


        for (String s1 : group1To4DetailsFs1) {
            // 表示X7之类的
            if (all.contains(s1) && !group2.contains(s1)) {
                group2.add(s1);
            } else {
                // 表示组7
                String group = extractGroupNumber(s1);
                if (("7".equals(group) || "8".equals(group)) && !group2.contains(s1)) {
                    group2.add(s1);
                }
            }
        }

        // 不会出现这个情况  可以不删除
        /*if (group1.size() == 0 && group2.size() == 0) {
            return true;
        }*/

        int count = 0;
        if (group1.size() > group2.size()) {
            for (String s1 : group2) {
                if (group1.contains(s1)) {
                    count++;
                }
            }
        } else {
            for (String s1 : group1) {
                if (group2.contains(s1)) {
                    count++;
                }
            }
        }
        return count >= 1;

    }

    // 提取某些组的详情
    private List<String> getGroupDetails(List<String> details, int start, int end) {
        List<String> result = new ArrayList<>();
        for (String detail : details) {
            String group = extractGroupNumber(detail);
            int groupNumber = 0;
            if (!group.equals("")) {
                groupNumber = Integer.parseInt(group);
            }
            if (groupNumber >= start && groupNumber <= end) {
                result.add(detail);
            }
        }
        return result;
    }

    // 提取组号
    private String extractGroupNumber(String faultDetail) {
        // 假设组号的格式为 d717b组1，6d2bc组2，X3，X10，从字符串中提取数字
        // 提取组号部分的数字
        return faultDetail.replaceAll(".*(组|X)(\\d+)", "$2");
//        String[] parts = faultDetail.split("组");
//        return parts.length > 1 ? parts[1] : null;
    }
}
